#include "BaseType.h"
#include "Tracer.h"
#include "Singleton.h"
using namespace libemb;

/**
 * 工厂方法：
 * 1.一个抽象产品类,可以派生多个具体产品类
 * 2.一个抽象工厂类,可以派生多个具体工厂类
 * 3.每个具体工厂只能创建一种具体产品
 * 使用场景：
 * 1.创建新产品时只需要增加一个对应的新工厂就可以，不需要修改原来的代码
 **/

//汽车
class Car{
DECL_CLASSNAME(Car)
public:
    virtual void run()=0;
};

class TeslaCar:public Car{
DECL_CLASSNAME(TeslaCar) 
public:
    void run() override
    {
        TRACE_DBG_CLASS("I am Tesla Car, I can run!");
    }
};

class AppleCar:public Car{
DECL_CLASSNAME(AppleCar) 
public:
    void run() override
    {
        TRACE_DBG_CLASS("I am Apple Car, I can run!");
    }
};


class CarFactory{
DECL_CLASSNAME(CarFactory)
public:
    virtual std::shared_ptr<Car> createCar()=0;
};

//TeslaFactory
class TeslaFactory:public CarFactory,public Singleton<TeslaFactory>{
DECL_CLASSNAME(TeslaFactory)
DECL_SINGLETON(TeslaFactory)
public:
    //生产汽车
    std::shared_ptr<Car> createCar()
    {
        return std::make_shared<TeslaCar>();
    }
};

TeslaFactory::TeslaFactory()
{
}

//Apple Factory
class AppleFactory:public CarFactory,public Singleton<AppleFactory>{
DECL_CLASSNAME(AppleFactory)
DECL_SINGLETON(AppleFactory)
public:
    //生产汽车
    std::shared_ptr<Car> createCar()
    {
        return std::make_shared<AppleCar>();
    }
};

AppleFactory::AppleFactory()
{
}

int main()
{
    Tracer::getInstance().setLevel(TRACE_LEVEL_DBG);
	Tracer::getInstance().addSink(std::make_shared<STDSink>()).start();

    auto& tesla = TeslaFactory::getInstance();
    tesla.createCar()->run();

    auto& apple = AppleFactory::getInstance();
    apple.createCar()->run();

    return RC_OK;
}